/**************************************************************************
Step 1. Include necessary header files such that the stuff your test logic needs is declared. 
Don't forget gtest.h, which declares the testing framework.                                                   
**************************************************************************/
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>

#include "gtest/gtest.h"
#include "include/pf_list.h"
#include "include/pf_internal.h"


/**************************************************************************
Step 2. Use test fixture to design your complex cases. 
You can add SetUp() to initialize the test data and 
TearDown() to clear the test data for common usage
Pls remember that when you using test fixture, need to use macro "TEST_F" instead of "TEST"                                                 
**************************************************************************/
class PfListTest : public testing::Test 
{
    /* This SetUp() will be called before every TEST CASE which is marked by macro "TEST_F" */
    virtual void SetUp() 
    {

    }

    /* This TearDown will be called after every TEST CASE which is marked by macro "TEST_F" */
    virtual void TearDown() 
    {

    }

};

static int normal_comp(const void* n1, const void* n2)
{
    return strcmp((const char*)n1, (const char*)n2);
}

static int empty_comp(const void* n1, const void* n2)
{
	EXPECT_EQ(0, -1);
    return strcmp((const char*)n1, (const char*)n2);
}

static int empty_cb(void* arg, pf_list_node_t* node)
{
    PF_UNUSED(node);
	EXPECT_EQ((void*)NULL, arg);
	EXPECT_EQ(0, -1);
    return 0;
}

static int count_cb(void* arg, pf_list_node_t* node)
{
    PF_UNUSED(node);
    *((int*)arg) += 1;
    return 0;
}

static int check_sort_cb(void* arg, pf_list_node_t* node)
{
    char* value    = NULL;
    char* prev_val = NULL;

    prev_val = *(char**)arg;
    value = (char*)pf_list_get_value(node);
    if(prev_val == NULL)
    {
        return 0;
    }
    if(value == NULL)
    {
        return -1;
    }
    if(normal_comp(prev_val, value) > 0 )
    {
        return -1;
    }

    *(char **)arg = value;
    return 0;
}

static int err_cb(void* arg, pf_list_node_t* node)
{
    PF_UNUSED(arg);
    PF_UNUSED(node);
    return -1;
}

static int get_rand()
{
        return 'a' + (int)((20.0 * rand())/(RAND_MAX + 1.0));
}

/***************************************************************************
Step 3. Use macro "TEST_F" to start your test case                                      
You can design your test case as the example
***************************************************************************/
TEST_F(PfListTest, EmptyListTest)
{
    /* Define the local variables */
    int ret              = -1;
    int count            = 0;
    pf_list_t* list      = NULL;
    pf_list_node_t* node = NULL;

    /* initilize test data for this case */
    list = pf_list_create();
	EXPECT_NE((void*)NULL, list);

    /* Call your function for test */
    /* Check the result */
    node = pf_list_head(list);
	EXPECT_EQ((void*)NULL, node);

    node = pf_list_tail(list);
	EXPECT_EQ((void*)NULL, node);

    count = pf_list_count(list);
	EXPECT_EQ(0, count);

    ret = pf_list_for_each(list, 0, NULL, empty_cb);
	EXPECT_EQ(0, ret);

    ret =  pf_list_sort(list, empty_comp);
	EXPECT_EQ(0, ret);

    ret =  pf_list_qsort(list, empty_comp);
	EXPECT_EQ(0, ret);

    ret =  pf_list_clear(list);
	EXPECT_EQ(0, ret);

    /* Clear the test data for this case */

    ret = pf_list_destory(list);
	EXPECT_EQ(0, ret);
}

TEST_F(PfListTest, OneNodeListTest)
{
    /* Define the local variables */
    int ret              = -1;
    int count            = 0;
    pf_list_t* list      = NULL;
    pf_list_node_t* node = NULL;
    char* value          = NULL;

    /* initilize test data for this case */
    list = pf_list_create();
	EXPECT_NE((void*)NULL, list);

    /* Call your function for test */
    /* Check the result */
    ret = pf_list_push_front(list, (void*)"111");
	EXPECT_EQ(0, ret);

    node = pf_list_head(list);
	EXPECT_NE((void*)NULL, node);

    value = (char*)pf_list_get_value(node);
	EXPECT_NE((void*)NULL, value);
	EXPECT_STREQ("111", value);

    count = pf_list_count(list);
	EXPECT_EQ(1, count);

    node = pf_list_tail(list);
	EXPECT_NE((void*)NULL, node);

    value = (char*)pf_list_get_value(node);
	EXPECT_NE((void*)NULL, value);
	EXPECT_STREQ("111", value);

	EXPECT_EQ((void*)NULL, pf_list_next(node));
	EXPECT_EQ((void*)NULL, pf_list_prev(node));

    value = (char*)pf_list_erase(list, node);
	EXPECT_NE((void*)NULL, value);
	EXPECT_STREQ("111", value);

    ret = pf_list_push_back(list, (void*)"222");
	EXPECT_EQ(0, ret);

    count = 0;
    ret = pf_list_for_each(list, 0, &count, count_cb);
	EXPECT_EQ(0, ret);
	EXPECT_EQ(1, count);

    ret =  pf_list_sort(list, normal_comp);
	EXPECT_EQ(0, ret);

    ret =  pf_list_qsort(list, normal_comp);
	EXPECT_EQ(0, ret);

    ret = pf_list_insert(list, pf_list_head(list), (void*)"333");
	EXPECT_EQ(0, ret);

    count = (int)pf_list_count(list);
	EXPECT_EQ(2, count);

    value = (char*)pf_list_pop_front(list);
	EXPECT_NE((void*)NULL, value);
	EXPECT_STREQ("222", value);

    count = (int)pf_list_count(list);
	EXPECT_EQ(1, count);

    value = (char*)pf_list_pop_back(list);
	EXPECT_NE((void*)NULL, value);
	EXPECT_STREQ("333", value);

    count = (int)pf_list_count(list);
	EXPECT_EQ(0, count);

    ret = pf_list_insert(list, pf_list_head(list), (void*)"444");
	EXPECT_EQ(0, ret);

    count = (int)pf_list_count(list);
	EXPECT_EQ(1, count);

    ret = pf_list_clear(list);
	EXPECT_EQ(0, ret);

    count = (int)pf_list_count(list);
	EXPECT_EQ(0, count);

    /* NULL node test */
    value = (char*)pf_list_erase(list, NULL);
    EXPECT_EQ((void*)NULL, value);

    ret = pf_list_push_back(list, (void*)"555");
	EXPECT_EQ(0, ret);

    count = 0;
    ret = pf_list_for_each(list, 1, &count, count_cb);
	EXPECT_EQ(0, ret);
	EXPECT_EQ(1, count);

    ret = pf_list_for_each(list, 0, NULL, err_cb);
	EXPECT_EQ(-1, ret);

    ret = pf_list_for_each(list, 1, NULL, err_cb);
	EXPECT_EQ(-1, ret);

    value = (char*)pf_list_pop_front(list);
	EXPECT_NE((void*)NULL, value);
	EXPECT_STREQ("555", value);

    count = (int)pf_list_count(list);
	EXPECT_EQ(0, count);

    /* Clear the test data for this case */
    ret = pf_list_destory(list);
	EXPECT_EQ(0, ret);
}

TEST_F(PfListTest, ListSortTest)
{
    /* Define the local variables */
    int ret               = -1;
    int count             = 0;
    int i                 = 0;
    char* values[]        = {"103", "258", "", "026", "007", "829", "104", "456", "238", "926", 
                             "724", "127", "624", "315", "417", "919", "004", "274", "183"};
    char* sorted_values[] = {"", "004", "007", "026", "103", "104", "127", "183", "238", "258",
                             "274", "315", "417", "456", "624", "724", "829", "919", "926" };
    pf_list_t* list       = NULL;
    pf_list_node_t* node  = NULL;
    char* value           = NULL;

    /* initilize test data for this case */
    list = pf_list_create();
	EXPECT_NE((void*)NULL, list);

    for(i = 0; i < (int)PF_ARR_SIZE(values); i++)
    {
        ret = pf_list_push_back(list, (void*)values[i]);
        EXPECT_EQ(0, ret) << "i = " << i;
    }

    count = (int)pf_list_count(list);
    EXPECT_EQ((int)PF_ARR_SIZE(values), count);

    node = pf_list_head(list);
	EXPECT_NE((void*)NULL, node);

    i = 0;
    while(node != NULL)
    {
        value = (char*)pf_list_get_value(node);
        EXPECT_STREQ(values[i], value) << "i = " << i;
        i++;
        node = pf_list_next(node);
    }
    EXPECT_EQ((int)PF_ARR_SIZE(values), i);

    /* Call your function for test */
    /* Check the result */

    ret =  pf_list_sort(list, normal_comp);
	EXPECT_EQ(0, ret);

    node = pf_list_head(list);
	EXPECT_NE((void*)NULL, node);
	EXPECT_STREQ(sorted_values[0], (char*)pf_list_get_value(node));

    i = 0;
    while(node != NULL)
    {
        value = (char*)pf_list_get_value(node);
        EXPECT_STREQ(sorted_values[i], value) << "i = " << i;
        i++;
        node = pf_list_next(node);
    }
    EXPECT_EQ((int)PF_ARR_SIZE(sorted_values), i);

    node = pf_list_tail(list);
	EXPECT_NE((void*)NULL, node);
	EXPECT_STREQ(sorted_values[PF_ARR_SIZE(sorted_values) - 1], (char*)pf_list_get_value(node));

    /* NULL test */
    ret =  pf_list_sort(NULL, normal_comp);
	EXPECT_EQ(0, ret);

    /* Clear the test data for this case */
    ret = pf_list_destory(list);
	EXPECT_EQ(0, ret);
}

TEST_F(PfListTest, ListSortRandomTest)
{
    /* Define the local variables */
    int ret               = -1;
    int count             = 0;
    int i                 = 0;
    char values[10000][16] = {{0},};
    char sorted_values[10000][16] = {{0},};
    pf_list_t* list       = NULL;
    pf_list_node_t* node  = NULL;
    char* value           = NULL;
    char* prev_value      = NULL;

    /* initilize test data for this case */
    list = pf_list_create();
	EXPECT_NE((void*)NULL, list);

    /* Call your function for test */
    /* Check the result */
    /* random first time */
    srand((int)time(0));
    for(i = 0; i < (int)PF_ARR_SIZE(values); i++)
    {
        snprintf(values[i], sizeof(values[i]), "%c%c%c%c%c%c%c%c", 
            get_rand(), get_rand(), get_rand(), get_rand(),
            get_rand(), get_rand(), get_rand(), get_rand());
        memcpy(sorted_values[i], values[i], sizeof(sorted_values[i]));

        //ret = pf_list_push_back(list, (void*)values[i]);
        ret = pf_list_insert(list, pf_list_tail(list), (void*)values[i]);
        EXPECT_EQ(0, ret) << "i = " << i;
    }

    count = (int)pf_list_count(list);
    EXPECT_EQ((int)PF_ARR_SIZE(values), count);

    node = pf_list_head(list);
	EXPECT_NE((void*)NULL, node);

    i = 0;
    while(node != NULL)
    {
        value = (char*)pf_list_get_value(node);
        EXPECT_STREQ(values[i], value) << "i = " << i;
        i++;
        node = pf_list_next(node);
    }
    EXPECT_EQ((int)PF_ARR_SIZE(values), i);

    ret =  pf_list_sort(list, normal_comp);
	EXPECT_EQ(0, ret);

    ret = pf_list_for_each(list, 1, &prev_value, check_sort_cb);
    EXPECT_EQ(0, ret);

    /* qsort expect values */
    qsort(sorted_values, PF_ARR_SIZE(sorted_values), sizeof(sorted_values[0]), normal_comp);
    
    /* check list head */
    node = pf_list_head(list);
	EXPECT_NE((void*)NULL, node);
	EXPECT_STREQ(sorted_values[0], (char*)pf_list_get_value(node));

    /* check sorted list values */
    i = 0;
    while(node != NULL)
    {
        value = (char*)pf_list_get_value(node);
        EXPECT_STREQ(sorted_values[i], value) << "i = " << i;
        i++;
        node = pf_list_next(node);
    }
    EXPECT_EQ((int)PF_ARR_SIZE(sorted_values), i);

    /* check list tail */
    node = pf_list_tail(list);
	EXPECT_NE((void*)NULL, node);
	EXPECT_STREQ(sorted_values[PF_ARR_SIZE(sorted_values) - 1], (char*)pf_list_get_value(node));

    ret = pf_list_clear(list);
    EXPECT_EQ(0, ret);

    /* random second time */
    srand((int)time(0));
    for(i = 0; i < (int)PF_ARR_SIZE(values); i++)
    {
        snprintf(values[i], sizeof(values[i]), "%c%c%c%c%c%c%c%c", 
            get_rand(), get_rand(), get_rand(), get_rand(),
            get_rand(), get_rand(), get_rand(), get_rand());
        memcpy(sorted_values[i], values[i], sizeof(sorted_values[i]));

        ret = pf_list_push_front(list, (void*)values[i]);
        EXPECT_EQ(0, ret) << "i = " << i;
    }

    count = (int)pf_list_count(list);
    EXPECT_EQ((int)PF_ARR_SIZE(values), count);

    ret =  pf_list_sort(list, normal_comp);
	EXPECT_EQ(0, ret);

    ret = pf_list_for_each(list, 1, &prev_value, check_sort_cb);
    EXPECT_EQ(0, ret);

    /* qsort expect values */
    qsort(sorted_values, PF_ARR_SIZE(sorted_values), sizeof(sorted_values[0]), normal_comp);
    
    /* check list head */
    node = pf_list_head(list);
	EXPECT_NE((void*)NULL, node);
	EXPECT_STREQ(sorted_values[0], (char*)pf_list_get_value(node));

    /* check sorted list values */
    i = 0;
    while(node != NULL)
    {
        value = (char*)pf_list_get_value(node);
        EXPECT_STREQ(sorted_values[i], value) << "i = " << i;
        i++;
        node = pf_list_next(node);
    }
    EXPECT_EQ((int)PF_ARR_SIZE(sorted_values), i);

    /* check list tail */
    node = pf_list_tail(list);
	EXPECT_NE((void*)NULL, node);
	EXPECT_STREQ(sorted_values[PF_ARR_SIZE(sorted_values) - 1], (char*)pf_list_get_value(node));

    /* clear list */
    for(i = 0 ; i < (int)PF_ARR_SIZE(values); i++)
    {
        value = (char*)pf_list_pop_front(list);
        EXPECT_NE((void*)NULL, value) << "i = " << i;
    }

    count = (int)pf_list_count(list);
    EXPECT_EQ(0, count);


    /* random third time */
    srand((int)time(0));
    for(i = 0; i < (int)PF_ARR_SIZE(values); i++)
    {
        snprintf(values[i], sizeof(values[i]), "%c%c%c%c%c%c%c%c", 
            get_rand(), get_rand(), get_rand(), get_rand(),
            get_rand(), get_rand(), get_rand(), get_rand());
        memcpy(sorted_values[i], values[i], sizeof(sorted_values[i]));

        ret = pf_list_insert(list, pf_list_head(list), (void*)values[i]);
        EXPECT_EQ(0, ret) << "i = " << i;
    }

    count = (int)pf_list_count(list);
    EXPECT_EQ((int)PF_ARR_SIZE(values), count);

    ret =  pf_list_sort(list, normal_comp);
	EXPECT_EQ(0, ret);

    ret = pf_list_for_each(list, 1, &prev_value, check_sort_cb);
    EXPECT_EQ(0, ret);

    /* qsort expect values */
    qsort(sorted_values, PF_ARR_SIZE(sorted_values), sizeof(sorted_values[0]), normal_comp);
    
    /* check list head */
    node = pf_list_head(list);
	EXPECT_NE((void*)NULL, node);
	EXPECT_STREQ(sorted_values[0], (char*)pf_list_get_value(node));

    /* check sorted list values */
    i = 0;
    while(node != NULL)
    {
        value = (char*)pf_list_get_value(node);
        EXPECT_STREQ(sorted_values[i], value) << "i = " << i;
        i++;
        node = pf_list_next(node);
    }
    EXPECT_EQ((int)PF_ARR_SIZE(sorted_values), i);

    /* check list tail */
    node = pf_list_tail(list);
	EXPECT_NE((void*)NULL, node);
	EXPECT_STREQ(sorted_values[PF_ARR_SIZE(sorted_values) - 1], (char*)pf_list_get_value(node));

    /* clear list */
    for(i = 0 ; i < (int)PF_ARR_SIZE(values); i++)
    {
        value = (char*)pf_list_pop_back(list);
        EXPECT_NE((void*)NULL, value) << "i = " << i;
    }

    count = (int)pf_list_count(list);
    EXPECT_EQ(0, count);

    /* Clear the test data for this case */
    ret = pf_list_destory(list);
	EXPECT_EQ(0, ret);
}

TEST_F(PfListTest, ListQSortTest)
{
    /* Define the local variables */
    int ret               = -1;
    int count             = 0;
    int i                 = 0;
    char* values[]        = {"103", "258", "", "026", "007", "829", "104", "456", "238", "926", 
                             "724", "127", "624", "315", "417", "919", "004", "274", "183"};
    char* sorted_values[] = {"", "004", "007", "026", "103", "104", "127", "183", "238", "258",
                             "274", "315", "417", "456", "624", "724", "829", "919", "926" };
    pf_list_t* list       = NULL;
    pf_list_node_t* node  = NULL;
    char* value           = NULL;

    /* initilize test data for this case */
    list = pf_list_create();
	EXPECT_NE((void*)NULL, list);

    for(i = 0; i < (int)PF_ARR_SIZE(values); i++)
    {
        ret = pf_list_push_back(list, (void*)values[i]);
        EXPECT_EQ(0, ret) << "i = " << i;
    }

    count = (int)pf_list_count(list);
    EXPECT_EQ((int)PF_ARR_SIZE(values), count);

    node = pf_list_head(list);
	EXPECT_NE((void*)NULL, node);

    i = 0;
    while(node != NULL)
    {
        value = (char*)pf_list_get_value(node);
        EXPECT_STREQ(values[i], value) << "i = " << i;
        i++;
        node = pf_list_next(node);
    }
    EXPECT_EQ((int)PF_ARR_SIZE(values), i);

    /* Call your function for test */
    /* Check the result */

    ret =  pf_list_qsort(list, normal_comp);
	EXPECT_EQ(0, ret);

    node = pf_list_head(list);
	EXPECT_NE((void*)NULL, node);
    i = 0;
    while(node != NULL)
    {
        value = (char*)pf_list_get_value(node);
        EXPECT_STREQ(sorted_values[i], value) << "i = " << i;
        i++;
        node = pf_list_next(node);
    }
    EXPECT_EQ((int)PF_ARR_SIZE(sorted_values), i);



    /* NULL test */
    ret =  pf_list_qsort(NULL, normal_comp);
	EXPECT_EQ(0, ret);

    /* Clear the test data for this case */
    ret = pf_list_destory(list);
	EXPECT_EQ(0, ret);
}

TEST_F(PfListTest, ListQSortRandomTest)
{
    /* Define the local variables */
    int ret               = -1;
    int count             = 0;
    int i                 = 0;
    char values[10000][16] = {{0},};
    char sorted_values[10000][16] = {{0},};
    pf_list_t* list       = NULL;
    pf_list_node_t* node  = NULL;
    char* value           = NULL;
    char* prev_value      = NULL;

    /* initilize test data for this case */
    list = pf_list_create();
	EXPECT_NE((void*)NULL, list);

    /* Call your function for test */
    /* Check the result */
    /* random first time */
    srand((int)time(0));
    for(i = 0; i < (int)PF_ARR_SIZE(values); i++)
    {
        snprintf(values[i], sizeof(values[i]), "%c%c%c%c%c%c%c%c", 
            get_rand(), get_rand(), get_rand(), get_rand(),
            get_rand(), get_rand(), get_rand(), get_rand());
        memcpy(sorted_values[i], values[i], sizeof(sorted_values[i]));

        //ret = pf_list_push_back(list, (void*)values[i]);
        ret = pf_list_insert(list, pf_list_tail(list), (void*)values[i]);
        EXPECT_EQ(0, ret) << "i = " << i;
    }

    count = (int)pf_list_count(list);
    EXPECT_EQ((int)PF_ARR_SIZE(values), count);

    node = pf_list_head(list);
	EXPECT_NE((void*)NULL, node);

    i = 0;
    while(node != NULL)
    {
        value = (char*)pf_list_get_value(node);
        EXPECT_STREQ(values[i], value) << "i = " << i;
        i++;
        node = pf_list_next(node);
    }
    EXPECT_EQ((int)PF_ARR_SIZE(values), i);

    ret =  pf_list_qsort(list, normal_comp);
	EXPECT_EQ(0, ret);

    ret = pf_list_for_each(list, 1, &prev_value, check_sort_cb);
    EXPECT_EQ(0, ret);

    /* qsort expect values */
    qsort(sorted_values, PF_ARR_SIZE(sorted_values), sizeof(sorted_values[0]), normal_comp);
    
    /* check list head */
    node = pf_list_head(list);
	EXPECT_NE((void*)NULL, node);
	EXPECT_STREQ(sorted_values[0], (char*)pf_list_get_value(node));

    /* check sorted list values */
    i = 0;
    while(node != NULL)
    {
        value = (char*)pf_list_get_value(node);
        EXPECT_STREQ(sorted_values[i], value) << "i = " << i;
        i++;
        node = pf_list_next(node);
    }
    EXPECT_EQ((int)PF_ARR_SIZE(sorted_values), i);

    /* check list tail */
    node = pf_list_tail(list);
	EXPECT_NE((void*)NULL, node);
	EXPECT_STREQ(sorted_values[PF_ARR_SIZE(sorted_values) - 1], (char*)pf_list_get_value(node));

    ret = pf_list_clear(list);
    EXPECT_EQ(0, ret);

    /* random second time */
    srand((int)time(0));
    for(i = 0; i < (int)PF_ARR_SIZE(values); i++)
    {
        snprintf(values[i], sizeof(values[i]), "%c%c%c%c%c%c%c%c", 
            get_rand(), get_rand(), get_rand(), get_rand(),
            get_rand(), get_rand(), get_rand(), get_rand());
        memcpy(sorted_values[i], values[i], sizeof(sorted_values[i]));

        ret = pf_list_push_front(list, (void*)values[i]);
        EXPECT_EQ(0, ret) << "i = " << i;
    }

    count = (int)pf_list_count(list);
    EXPECT_EQ((int)PF_ARR_SIZE(values), count);

    ret =  pf_list_qsort(list, normal_comp);
	EXPECT_EQ(0, ret);

    ret = pf_list_for_each(list, 1, &prev_value, check_sort_cb);
    EXPECT_EQ(0, ret);

    /* qsort expect values */
    qsort(sorted_values, PF_ARR_SIZE(sorted_values), sizeof(sorted_values[0]), normal_comp);
    
    /* check list head */
    node = pf_list_head(list);
	EXPECT_NE((void*)NULL, node);
	EXPECT_STREQ(sorted_values[0], (char*)pf_list_get_value(node));

    /* check sorted list values */
    i = 0;
    while(node != NULL)
    {
        value = (char*)pf_list_get_value(node);
        EXPECT_STREQ(sorted_values[i], value) << "i = " << i;
        i++;
        node = pf_list_next(node);
    }
    EXPECT_EQ((int)PF_ARR_SIZE(sorted_values), i);

    /* check list tail */
    node = pf_list_tail(list);
	EXPECT_NE((void*)NULL, node);
	EXPECT_STREQ(sorted_values[PF_ARR_SIZE(sorted_values) - 1], (char*)pf_list_get_value(node));

    /* clear list */
    for(i = 0 ; i < (int)PF_ARR_SIZE(values); i++)
    {
        value = (char*)pf_list_pop_front(list);
        EXPECT_NE((void*)NULL, value) << "i = " << i;
    }

    count = (int)pf_list_count(list);
    EXPECT_EQ(0, count);


    /* random third time */
    srand((int)time(0));
    for(i = 0; i < (int)PF_ARR_SIZE(values); i++)
    {
        snprintf(values[i], sizeof(values[i]), "%c%c%c%c%c%c%c%c", 
            get_rand(), get_rand(), get_rand(), get_rand(),
            get_rand(), get_rand(), get_rand(), get_rand());
        memcpy(sorted_values[i], values[i], sizeof(sorted_values[i]));

        ret = pf_list_insert(list, pf_list_head(list), (void*)values[i]);
        EXPECT_EQ(0, ret) << "i = " << i;
    }

    count = (int)pf_list_count(list);
    EXPECT_EQ((int)PF_ARR_SIZE(values), count);

    ret =  pf_list_qsort(list, normal_comp);
	EXPECT_EQ(0, ret);

    ret = pf_list_for_each(list, 1, &prev_value, check_sort_cb);
    EXPECT_EQ(0, ret);

    /* qsort expect values */
    qsort(sorted_values, PF_ARR_SIZE(sorted_values), sizeof(sorted_values[0]), normal_comp);
    
    /* check list head */
    node = pf_list_head(list);
	EXPECT_NE((void*)NULL, node);
	EXPECT_STREQ(sorted_values[0], (char*)pf_list_get_value(node));

    /* check sorted list values */
    i = 0;
    while(node != NULL)
    {
        value = (char*)pf_list_get_value(node);
        EXPECT_STREQ(sorted_values[i], value) << "i = " << i;
        i++;
        node = pf_list_next(node);
    }
    EXPECT_EQ((int)PF_ARR_SIZE(sorted_values), i);

    /* check list tail */
    node = pf_list_tail(list);
	EXPECT_NE((void*)NULL, node);
	EXPECT_STREQ(sorted_values[PF_ARR_SIZE(sorted_values) - 1], (char*)pf_list_get_value(node));

    /* clear list */
    for(i = 0 ; i < (int)PF_ARR_SIZE(values); i++)
    {
        value = (char*)pf_list_pop_back(list);
        EXPECT_NE((void*)NULL, value) << "i = " << i;
    }

    count = (int)pf_list_count(list);
    EXPECT_EQ(0, count);

    /* Clear the test data for this case */
    ret = pf_list_destory(list);
	EXPECT_EQ(0, ret);
}
